package com.cms.service;

import com.cms.dao.SysResourceDao;
import com.cms.dao.SysRoleDao;
import com.cms.dao.SysRoleResourceDao;
import com.cms.dao.SysUserRoleDao;
import com.cms.model.bo.BussinessMsg;
import com.cms.model.vo.SysResource;
import com.cms.model.vo.SysRole;
import com.cms.model.vo.SysRoleResource;
import com.cms.utils.constant.BusinessConstants;
import com.cms.utils.constant.BussinessCode;
import com.cms.utils.tools.BussinessMsgUtil;
import com.cms.utils.tools.ParseObjectUtils;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.nutz.json.Json;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**角色信息服务类*/
@Service
public class SysRoleService extends BaseService<SysRole>{

    @Autowired
    private SysRoleDao roleDao;
    
    @Autowired
    private SysUserRoleDao userRoleDao;
    
    @Autowired
    private SysRoleResourceDao roleResourceDao;
    
    @Autowired
    private SysResourceDao resourceDao;
    
    @Autowired
    private ShiroService shiroService;
    

    /**
     * 角色信息分页显示
     * @param role 角色实体
     * @return
     */
    public String selectRoleResultPageList(SysRole role) {
    	PageHelper.startPage(role.getPage(),role.getLimit());
    	return setPage(this.selectRoleList(role));
    }

    /**
     * 角色列表信息List
     * @param role 角色实体
     * @return
     */
    public List<SysRole> selectRoleList(SysRole role){
        List<SysRole> roleList = roleDao.selectRoleList(role);
        if (null != roleList && !roleList.isEmpty()){
            for (SysRole r : roleList) {
            	SysRole rr = this.selectRoleResourcesByRoleId(r.getRoleId());
                r.setResourceIds(rr.getResourceIds());
                r.setResourceNames(rr.getResourceNames());
            }
        }
        return roleList;
    }

    /**
     * 批量角色状态失效
     * @param roleIds	角色Id
     * @param loginName 当前登录用户名
     * @return
     * @throws Exception
     */
    public BussinessMsg updateRoleBatchStatus(String[] roleIds,String loginName) throws Exception{
        logger.info("批量失效角色开始，当前角色Id:"+Arrays.toString(roleIds));
        long start = System.currentTimeMillis();
        try {
            if(null != roleIds && roleIds.length > 0){
            	String nroleIds = StringUtils.join(roleIds,",");
                //解除用户与角色绑定关系
            	userRoleDao.deleteUserRoleByRoleId(nroleIds);
            	//解除角色与菜单绑定关系
                roleResourceDao.deleteRoleResourceByRoleId(nroleIds);
                //更改角色状态为1-失效
                Map<String, Object> params = new HashMap<String, Object>();
                params.put("roleStatus", BusinessConstants.SYS_STATUS_1.getCode());
                params.put("modifier", loginName);
                params.put("modifierTime", new Date());
                params.put("roleIds", roleIds);
                roleDao.updateRoleByStatus(params);
                //清空用户权限缓存信息
                shiroService.clearAllCacheAuth();
            }
        } catch (Exception e) {
            logger.error("批量失效角色方法内部错误",e);
            throw e;
        }finally {
            logger.info("批量失效角色结束,用时" + (System.currentTimeMillis() - start) + "毫秒");
        }
        return BussinessMsgUtil.returnCodeMessage(BussinessCode.GLOBAL_SUCCESS);
    }


    /**
     * 保存角色信息
     *
     * @param role      角色对象
     * @param loginName 当前登录用户
     * @return
     * @throws Exception
     */
    @Transactional
    public BussinessMsg saveOrUpdateRole(SysRole role, String loginName) throws Exception {
        logger.info("保存用户角色开始");
        long start = System.currentTimeMillis();
        try {
            //验证角色名称唯一性
            Long checkRoleName = roleDao.selectRoleNameCheck(role.getRoleName(),role.getRoleId());
            if(checkRoleName.intValue() > 0){
                return BussinessMsgUtil.returnCodeMessage(BussinessCode.ROLE_NAME_EXIST);
            }
            //保存角色信息
            if (null == role.getRoleId()) {
                role.setCreator(loginName);
                role.setCreateTime(new Date());
                roleDao.insertSelective(role);
            } else {
                //更新角色
                role.setModifier(loginName);
                role.setModifierTime(new Date());
                roleDao.updateByPrimaryKeySelective(role);
            }
        } catch (Exception e) {
            logger.error("保存角色方法内部错误", e);
            throw e;
        } finally {
            logger.info("保存角色信息结束,用时" + (System.currentTimeMillis() - start) + "毫秒");
        }
        return BussinessMsgUtil.returnCodeMessage(BussinessCode.GLOBAL_SUCCESS);
    }


    /**
     * 查询状态为有效,待分配的角色信息(用以用户分配角色时显示)
     * @param roleIds 已分配角色Id,以逗号分割
     */
    public String selectUserRoleByRoleIdList(String roleIds){
        Map<String, Object> map = new HashMap<String, Object>();
        //如果已给用户分配角色,则待分配用户显示栏中去除已分配的角色信息
        if(StringUtils.isNotEmpty(roleIds)){
            Integer[] roleIdInt = ParseObjectUtils.strArrayToIntArray(roleIds);
            List<SysRole> lists = roleDao.selectUserRoleByRoleIdList(roleIdInt);
            map.put("rows", lists);
            return Json.toJson(map);
        }
        map.put("rows", roleDao.selectRoleListByStatus());
        //没有给用户分配角色,待分配显示栏中显示所有角色信息
        return Json.toJson(map);
    }
    
    /**
     * 查询状态为有效,已分配的角色信息(用已用户分配角色显示)
     * @param roleIds 角色Id
     * @return
     */
    public String selectDeceasedUserRoleByRoleIdList(String roleIds){
        Map<String, Object> map = new HashMap<String, Object>();
        //没有给用户分配角色，则已分配角色列表为空
        if(StringUtils.isNotEmpty(roleIds)){
            Integer[] roleIdInt = ParseObjectUtils.strArrayToIntArray(roleIds);
            List<SysRole> lists = roleDao.selectDeceasedUserRoleByRoleIdList(roleIdInt);
            map.put("rows", lists);
            return Json.toJson(map);
        }
        return null;
    }

    /**
     * 根据roleId查询角色资源信息
     * @param roleId 角色Id
     * @return
     */
    public SysRole selectRoleResourcesByRoleId(Integer roleId){
        StringBuilder sb = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();
        if(null != roleId){
            SysRole role = roleDao.selectByPrimaryKey(roleId);
            List<SysRoleResource> roleRes =  roleResourceDao.selectRoleResourceByRoleId(roleId);
            if(null != roleRes && !roleRes.isEmpty()){
                for (SysRoleResource r : roleRes) {
                    SysResource res = resourceDao.selectByPrimaryKey(r.getResourceId());
                    if(res != null){
                        //取得当前角色所属资源的ID以逗号拼接
                        sb.append(res.getResId()).append(",");
                        //取得当前角色所属资源的名称以逗号拼接
                        sb2.append(res.getResName()).append(",");
                    }
                }
                //将拼接后的资源信息的最后一个逗号删除
                if(sb.length()>0){
                    sb.deleteCharAt(sb.length()-1);
                }
                if(sb2.length()>0){
                    sb2.deleteCharAt(sb2.length()-1);
                }
            }
            //赋给角色实体,方便页面显示
            role.setResourceNames(sb2.toString());
            role.setResourceIds(sb.toString());
            return role;
        }
        return null;
    }


    /**
     * 保存角色信息授权信息
     * @param roleId        角色Id
     * @param resourceIds    资源Id数组
     * @param loginName     当前登陆用户名
     * @return
     * @throws Exception
     */
    @Transactional
    public BussinessMsg saveOrUpdateRoleResource(Integer roleId, Integer[] resourceIds,String loginName) throws Exception {
        logger.info("保存角色信息授权信息开始,参数,roleId:"+roleId+",resourceIds:"+ Arrays.toString(resourceIds));
        long start = System.currentTimeMillis();
        try {
            if(null != resourceIds && resourceIds.length > 0){
                List<SysRoleResource> roleNotRes  = roleResourceDao.selectRoleResourceByRoleId(roleId);
                if(null!= roleNotRes && !roleNotRes.isEmpty()){
                    for (SysRoleResource roleNotRe : roleNotRes) {
                    	roleResourceDao.deleteByPrimaryKey(roleNotRe.getRoleResId());
                    }
                }
                for (Integer resourceId : resourceIds) {
                    //保存角色资源信息
                    SysRoleResource roleResource = new SysRoleResource();
                    roleResource.setRoleId(roleId);
                    roleResource.setResourceId(resourceId);
                    roleResource.setCreator(loginName);
                    roleResource.setCreateTime(new Date());
                    roleResourceDao.insertSelective(roleResource);
                }

            }else{   //如果资源Id为空，则清空当前角色所有的菜单资源信息
            	roleResourceDao.deleteRoleResourceByRoleId(String.valueOf(roleId));
            }
            // 清空用户权限缓存信息
            shiroService.clearAllCacheAuth();
        } catch (Exception e) {
            logger.error("保存角色信息授权信息方法内部错误", e);
            throw e;
        } finally {
            logger.info("保存角色信息授权信息结束,用时" + (System.currentTimeMillis() - start) + "毫秒");
        }
        return BussinessMsgUtil.returnCodeMessage(BussinessCode.GLOBAL_SUCCESS);
    }
}
